package show.me.the.money.util.xml;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;


import org.apache.commons.lang.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Attribute;

@SuppressWarnings("unchecked")
public class MangoDBXMLUtils {
	public static final String FN_TAG_NAME = "_TAGNAME";
	public static final String FN_CHILDREN_ELEMENTS = "_CHILDREN";
	public static final String FN_ELEMENT_TEXT = "_TEXT";
	public static final String FN_ENCODING = "_ENCODING";
	public static final String SYS_ID = "_id";
	
	public static DBObject convert2DBObject(Document doc){
		if(doc == null){
			return null;
		}
		String encoding = doc.getXMLEncoding();
		Element root = doc.getRootElement();
		String _id = root.attributeValue("id");
		DBObject dbo = convert2DBObject(root);
		dbo.put(FN_ENCODING, encoding);
		dbo.put(SYS_ID, _id);    // set  _id
		return dbo;
	}
	
	public static DBObject convert2DBObject(Element root){
		DBObject o = new BasicDBObject();
		o.put(FN_TAG_NAME, root.getName());
		List<Attribute> attrs = root.attributes();
		for(Attribute attr:attrs){
			o.put(attr.getName(), attr.getValue());
		}
		List<Element> els = root.elements();
		if(els.size() > 0){
			List<DBObject> c = new ArrayList<DBObject>();
			for(Element el:els){
				c.add(convert2DBObject(el));
			}
			o.put(FN_CHILDREN_ELEMENTS, c);
		}
		else{
			String text = root.getText();
			if(!StringUtils.isEmpty(text)){
				o.put(FN_ELEMENT_TEXT,text);
			}
		}
		return o;
	}
	
	public static Document covert2XMLDocument(DBObject o){
		Document doc = DocumentHelper.createDocument();
		Element root = covert2XMLElement(o);
		doc.setRootElement(root);
		String encoding = (String)o.get(FN_ENCODING);
		if(StringUtils.isEmpty(encoding)){
			encoding = "UTF-8";
		}
		doc.setXMLEncoding(encoding);
		return doc;
	}
	
	
	public static Element covert2XMLElement(DBObject o){
		String tagName = (String)o.get(FN_TAG_NAME);
		Element root = DocumentHelper.createElement(tagName);
		Set<String> set = o.keySet();
		for(String nm : set){
			if(nm.startsWith("_")){
				continue;
			}
			String v = (String)o.get(nm);
			root.addAttribute(nm, v);
		}
		if(o.containsField(FN_CHILDREN_ELEMENTS)){
			List<DBObject> ls = (List<DBObject>)o.get(FN_CHILDREN_ELEMENTS);
			for(DBObject dbo : ls){
				Element child =covert2XMLElement(dbo);
				root.add(child);
			}
		}
		if(o.containsField(FN_ELEMENT_TEXT)){
			String v = (String)o.get(FN_ELEMENT_TEXT);
			root.setText(v);
		}
		return root;
	}
	
}
